home *** CD-ROM | disk | FTP | other *** search
- ;* STDIO.ASM
- ;************************************************************************
- ;* *
- ;* PC Scheme/Geneva 4.00 Borland TASM code *
- ;* *
- ;* (c) 1985-1988 by Texas Instruments, Inc. See COPYRIGHT.TXT *
- ;* (c) 1992 by L. Bartholdi & M. Vuilleumier, University of Geneva *
- ;* *
- ;*----------------------------------------------------------------------*
- ;* *
- ;* Standard Input-Output (interpreter support) *
- ;* *
- ;*----------------------------------------------------------------------*
- ;* *
- ;* Created by: John Jensen Date: 1985 *
- ;* Revision history: *
- ;* - 21 Nov 86: Detect disk full error correctly (rb) *
- ;* - 7 Jan 87: Added support for random I/O (dbs) *
- ;* - 10 Feb 87: EOF-DISP modified to reflect changes in page 5=syms (tc)*
- ;* - 16 Mar 87: Added Binary I/O, Error handling for Disk Full (tc) *
- ;* - 21 Jan 88: binary I/O uses line-length=0 (rb) *
- ;* - 18 Jun 92: Renaissance (Borland Compilers, ...) *
- ;* - 8 Jan 93: Whole window read interface moved to C (input.c) (mv) *
- ;* *
- ;* ``In nomine omnipotentii dei'' *
- ;************************************************************************
- IDEAL
- %PAGESIZE 60, 132
- MODEL medium
- LOCALS @@
-
- INCLUDE "scheme.ash"
-
- DATASEG
-
- prn_handle DW 0 ; printer handle
- handlee DW 0 ; handle
- pflags DW 0 ; port flags
- nlines DW 0 ; n_lines
- ncols DW 0 ; n_cols
- ulline DW 0 ; ul_line
- ulcol DW 0 ; ul_col
- curline DW 0 ; cur_line
- curcol DW 0 ; cur_col
- t_attrib DW 0 ; text attribute
- insert_m DW 1 ; insert mode (1 = on, 0 = off)
- index DW 0 ; index of buffer
- vidmode DW 0 ; detected video mode
-
- CODESEG
-
- ;********************************************************************
- ; *
- ; set_pos will set the file position, determing which chunk *
- ; of the file to read and then setting the file position to *
- ; the appropriate place. *
- ; *
- ;********************************************************************
- PROC C set_pos USES di, @@port, @@amt, @@buffer
- mov ax, 1
- call get_port C, [@@port], ax ; get port address
- mov bx, [tmp_reg.page]
- cmp [ptype+bx], PORTTYPE
- je @@goodport
- @@error:
- lea bx, [@@msg]
- DATASEG
- @@msg DB "SET-FILE-POSITION!", 0
- CODESEG
- mov ax, 3
- call set_src_error C, bx, ax, [@@port], [@@amt], [@@buffer]
- mov ax, -1
- jmp @@return
-
- @@goodport:
- mov bx, [tmp_reg.page]
- ldpage es, bx ; get page address of port
- mov si, [tmp_reg.disp]
- mov dx, [(PORTDEF es:si).pflags]
- and dx, PORT_TYPE
- jz @@error
- mov di, [@@amt]
- mov dx, [di]
- inc dx
- mov [(PORTDEF es:si).chunk], dx ; update chunk #
- dec dx
- xor bx, bx
- xchg bl, dh
- xchg dh, dl
- mov cx, bx
- test [(PORTDEF es:si).pflags], WRITE_MODE
- pushf
- jz @@readonly
- and [(PORTDEF es:si).pflags], NOT PORT_FLUSHED ; clear flushed bit
- mov bx, [@@buffer]
- add dx, [bx] ; add file position to chunk offset
- @@readonly:
- mov bx, [(PORTDEF es:si).handle]
- mov ax, 4200h ; move file pointer to offset dx
- int MSDOS
- popf
- jnz @@output ; jump if output port
-
- push ds es
- pop ds
- mov cx, 256 ; get buffer length
- mov bx, [(PORTDEF ds:si).handle]
- lea dx, [(PORTDEF ds:si).buffer]
- mov ah, 3fh
- int MSDOS ; read from a file
- pop ds
- mov [(PORTDEF es:si).bufend], ax ; save # bytes read
- @@output:
- mov bx, [@@buffer] ; get offset of chunk offset
- mov ax, [bx]
- mov [(PORTDEF es:si).bufpos], ax ; and save in port
- @@return:
- ret
- ENDP set_pos
-
- ;**************************************************************************
- ; Set Port Address
- ;**************************************************************************
- PROC C ssetadr USES si di bx, @@page:WORD, @@disp:WORD
- mov bx, [@@page]
- cmp [ptype+bx], PORTTYPE
- je @@goodport
- lea si, [@@msg]
- DATASEG
- @@msg DB "[VM INTERNAL ERROR] setadr: bad port", CR, LF, 0
- CODESEG
- call zprintf C, si
- call force_debug C
- mov ax, 1 ; return error status
- jmp @@return
-
- @@goodport:
- mov [port_reg.page], bx
- mov si, [@@disp]
- mov [port_reg.disp], si
- ldpage es, bx
- mov ax, [(PORTDEF es:si).handle]
- mov [handlee], ax
- mov ax, [(PORTDEF es:si).pflags]
- mov [pflags], ax
- xor ax, ax ; return status
- @@return:
- ret
- ENDP ssetadr
-
- ;**************************************************************************
- ; Input a Single Character
- ;**************************************************************************
- PROC C take_ch USES si di
- LOCAL @@leng:WORD, @@buffer:BYTE:BUFFSIZE, @@newbufpos:WORD
- mov [@@newbufpos], 0
- mov [@@leng], BUFFSIZE
- mov bx, [port_reg.page]
- ldpage es, bx
- mov si, [port_reg.disp]
-
- test [(PORTDEF es:si).pflags], WRITE_MODE
- jz @@readonly
- mov bx, [(PORTDEF es:si).pflags]
- and bx, PORT_FLUSHED+PORT_TYPE ;isolate appropriate flags
- cmp bx, TYPE_FILE ;buffer modified?
- jne @@readonly
- or [(PORTDEF es:si).pflags], PORT_FLUSHED ;clear flag
-
- ; this read was preceded by at least one write, so reposition file pointer
- ; so it rereads the buffer
- mov bx, [(PORTDEF es:si).handle]
- dec [(PORTDEF es:si).chunk]
- mov cx, [(PORTDEF es:si).chunk]
- xor dx, dx
- xchg dh, cl
- xchg cl, ch
- mov ax, 4200h ; reposition file pointer
- push si
- int MSDOS
- pop si
- mov bx, [(PORTDEF es:si).bufpos]
- mov [@@newbufpos], bx ; restore current buffer position
- jmp @@fromfile
-
- @@readonly:
- mov bx, [(PORTDEF es:si).bufpos]
- cmp bx, [(PORTDEF es:si).bufend]
- jge @@bufferempty
- jmp @@getnext
-
- @@bufferempty:
- test [pflags], TYPE_SOFTWARE ; file object ?
- jz @@notfromfile
- jmp @@fromfile
-
- @@notfromfile:
- test [pflags], TYPE_STRING ; read from string?
- jz @@fromwindow
- @@fromstring:
- lea ax, [@@leng]
- lea bx, [@@buffer]
- call stringrd C, [port_reg.page], [port_reg.disp], bx, ax
- test ax, ax ; check return status
- jnz @@error
- mov bx, [port_reg.page]
- ldpage es, bx
- mov si, [port_reg.disp]
- @@readchar:
- mov bx, [@@leng]
- jmp @@lengthset
-
- @@error:
- lea bx, [@@msg]
- DATASEG
- @@msg DB "[VM INTERNAL ERROR] takechar: source not a string", CR, LF, 0
- CODESEG
- call zprintf C, bx ; display error message
- jmp @@readchar
-
- @@fromwindow: ; read from window
- call read_win C
- mov bx, [port_reg.page]
- ldpage es, bx
- mov si, [port_reg.disp]
- mov bx, ax
- @@lengthset:
- mov [(PORTDEF es:si).bufend], bx ; save buffer length
- or bx, bx
- jnz @@buffergood
- mov [(PORTDEF es:si).bufpos], bx
- jmp @@sendeof
- @@buffergood:
- test [pflags], TYPE_SOFTWARE ; file object ?
- jnz @@notwindow
- test [pflags], TYPE_STRING ; or string ?
- jz @@getfirst
- @@notwindow: ; then copy chars from buffer
- push si
- lea di, [(PORTDEF si).buffer]
- lea si, [@@buffer]
- mov cx, bx ; length of characters to move
- cld ; direction forward
- rep movsb
- pop si
- @@getfirst:
- mov bx, [@@newbufpos]
- @@getnext: ; get the next char from input buffer
- xor ah, ah
- mov al, [(PORTDEF es:si+bx).buffer]
- inc bx
- mov [(PORTDEF es:si).bufpos], bx
- cmp al, CTRL_Z ; test for End-of-File
- jne @@return
- test [pflags], PORT_BINARY
- jnz @@return
- @@sendeof:
- mov ax, 256 ; text file, send EOF
- @@return:
- ret
-
- @@fromfile:
- cmp [(PORTDEF es:si).chunk], 1 ; operating on first chunk ?
- jne @@notfirst
- cmp [(PORTDEF es:si).bufpos], 0 ; buffer filled ?
- je @@bufferfilled
- @@notfirst:
- inc [(PORTDEF es:si).chunk] ; bump the chunk number
- @@bufferfilled:
- mov bx, [handlee]
- lea cx, [@@leng] ; address of length of bytes to read
- lea ax, [@@buffer] ; input buffer
- call zread C, bx, ax, cx
- or ax, ax
- jnz @@doserror
- jmp @@readchar
-
- @@doserror:
- add ax, (IO_ERRORS_START - 1) ; Make Dos I/O error number
- mov bx, 1
- lea cx, [port_reg]
- call dos_error C, bx, ax, cx ; invoke scheme error handler
- ENDP take_ch
-
- ;****************************************************************
- ; Output a single character
- ;****************************************************************
- PROC C givechar USES si di bx cx dx, @@char:WORD
- LOCAL @@length, @@vidmode
- mov [@@vidmode], -1
- cmp [trns_reg.page], 0 ; transcript file?
- jz @@notrans
- mov bx, [port_reg.page]
- mov si, [port_reg.disp]
- ldpage es, bx
- test [(PORTDEF es:si).flags], W_TRANS
- jz @@notrans
- push bx
- call ssetadr C, [trns_reg.page], [trns_reg.disp]
- call givechar C, [@@char] ; output to transcript file
- pop bx
- call ssetadr C, bx, si
- @@notrans:
- mov cx, [@@char]
- test [pflags], TYPE_SOFTWARE ; window ?
- jz @@towindow
- jmp @@tofile
- @@towindow:
- test [pflags], TYPE_STRING ; string ?
- jz @@@@notstring
- jmp @@return
- @@@@notstring:
-
- ;********************************************************************
- ; Output Character to Window
- ;
- ; Description:This routine writes a character to the current cursor
- ; position, then increments the cursor location.
- ; If the current cursor position is now within the bounds
- ; of the window, the character is output in the first
- ; column of the next line, scrolling the window, if
- ; necessary. The current text attributes are used to
- ; write the character.
- ; Note: cx = character
- ;********************************************************************
- mov bx, [port_reg.page]
- mov si, [port_reg.disp]
- ldpage es, bx
- test [pflags], WRITE_MODE ; get the port flag
- jnz @@open
- jmp @@return
- @@open:
- mov bx, [(PORTDEF es:si).curline]
- mov ax, [(PORTDEF es:si).curcol]
- mov dx, [(PORTDEF es:si).ulline]
- mov [ulline], dx
- mov dx, [(PORTDEF es:si).ulcol]
- mov [ulcol], dx
- mov dx, [(PORTDEF es:si).nlines]
- mov [nlines], dx
- mov dx, [(PORTDEF es:si).ncols]
- mov [ncols], dx
- mov dx, [(PORTDEF es:si).text]
- mov [t_attrib], dx
- @@null: ; Check for the character
- or cl, cl
- jnz @@backspace
- jmp @@return ; do nothing
-
- @@backspace:
- cmp cl, BACKSPACE ; backspace?
- jne @@bell
- dec ax
- or ax, ax
- jl @@backempty
- jmp @@updatecol
- @@backempty:
- xor ax, ax ; cur_col = 0
- jmp @@updatecol
-
- @@bell:
- cmp cl, BELL ; bell character?
- jne @@tab
- call zbell C ; sound the alarm
- jmp @@return
-
- @@tab:
- cmp cl, TAB ; tab character?
- jne @@linefeed
- mov cx, ax
- mov dx, 8 ; dl = 8
- div dl ; ah = (cur_col % 8)
- sub dl, ah
- add cx, dx
- mov ax, cx
- jmp @@updatecol
-
- @@linefeed:
- cmp cl, LF ; line feed?
- jne @@carriage
- xor ax, ax
- inc bx
- cmp bx, [nlines] ; out of lines?
- jge @@scroll
- jmp @@updateline
- @@scroll:
- call zscroll C, [ulline], [ulcol], [nlines], [ncols], [t_attrib]
- mov bx, [nlines]
- dec bx
- xor ax, ax
- jmp @@updateline
-
- @@carriage:
- cmp cl, CR
- jne @@allchars
- xor ax, ax ; return the carriage back home
- jmp @@updatecol
-
- @@clip: ; Support for @@allchars
- inc ax
- jmp @@updatecol
-
- @@allchars:
- cmp ax, [ncols] ; check end of line
- jl @@checkline
- mov dx, [(PORTDEF es:si).flags]
- and dx, W_WRAP
- jz @@clip
- inc bx ; wrap
- xor ax, ax
- @@checkline:
- cmp bx, [nlines] ; check out of lines?
- jl @@displaychar
- call zscroll C, [ulline], [ulcol], [nlines], [ncols], [t_attrib]
- mov bx, [nlines]
- dec bx ; set up current line number
- xor ax, ax ; and current column number
- @@displaychar:
- mov [curcol], ax
- mov [curline], bx
- add ax, [ulcol]
- add bx, [ulline]
- mov dl, [BYTE @@char]
- mov dh, [BYTE t_attrib]
- mov [@@length], 1
- lea cx, [@@vidmode]
- call zputc C, bx, ax, dx, [@@length], cx
- mov ax, [curcol]
- mov bx, [curline]
- inc ax ; increment current column
- @@updateline:
- mov [(PORTDEF es:si).curline], bx
- @@updatecol:
- mov [(PORTDEF es:si).curcol], ax
- jmp @@return
-
- ;************************************************************************
- ; Output character to file
- ;************************************************************************
- @@tofile:
- lea bx, [@@length] ; zwrite needs length = (int *)
- mov [WORD bx], 1
- lea si, [@@char]
- mov ax, [handlee]
- test [pflags], PORT_BINARY
- jnz @@outputchar
- cmp cl, LF ; line-feed ?
- jne @@outputchar
- mov [WORD si], CR ; then output carriage return
- jmp @@outputchar
-
- @@outputchar:
- call zwrite C, ax, si, bx
- or ax, ax
- jnz @@error
- cmp [@@length], 1
- jne @@diskfull
- test [pflags], PORT_BINARY ; Binary file ?
- jnz @@handlechar
- cmp [WORD si], CR ; carriage return ?
- jne @@handlechar
- mov ax, [handlee]
- lea si, [@@char]
- mov [WORD si], LF ; then add a line feed
- lea bx, [@@length]
- call zwrite C, ax, si, bx
- test ax, ax ; check return status
- jnz @@error
- cmp [@@length], 1
- je @@handlechar
- @@diskfull:
- mov ax, DISK_FULL_ERROR ; Note disk full error
- jmp @@doserror
-
- @@error:
- add ax, (IO_ERRORS_START - 1) ; make dos i/o error number
- @@doserror:
- mov bx, 1 ; 1 = unreturnable
- lea cx, [port_reg]
- call dos_error C, bx, ax, cx ; invoke scheme error handler
-
- @@handlechar:
- mov bx, [port_reg.page]
- ldpage es, bx
- mov bx, [WORD si] ; get the character
- mov si, [port_reg.disp]
- mov ax, [(PORTDEF es:si).curcol]
- test [pflags], PORT_BINARY ; Binary file?
- jnz @@checkboundary
- cmp bl, BACKSPACE ; back space?
- jne @@filetab
- dec ax
- or ax, ax
- jge @@checkboundary
- @@begofline:
- xor ax, ax
- jmp @@checkboundary
-
- @@filetab:
- cmp bl, TAB ; tab?
- jne @@fileCR
- mov cx, ax
- mov dx, 8
- div dl ; ah = (cur_col % 8)
- sub dl, ah
- add cx, dx
- mov ax, cx
- jmp @@checkboundary
-
- @@fileCR:
- cmp bl, CR ; carriage return?
- jne @@fileLF
- mov bl, LF ; yes, make it a linefeed
- jmp @@begofline
-
- @@fileLF:
- cmp bl, LF ; line feed?
- jne @@default
- jmp @@begofline
-
- @@default:
- cmp ax, [(PORTDEF es:si).ncols]
- jge @@begofline
- inc ax
-
- @@checkboundary:
- cmp [(PORTDEF es:si).ncols], 0
- je @@columnok
- mov [(PORTDEF es:si).curcol], ax
- @@columnok:
- mov ax, [(PORTDEF es:si).bufpos]
- inc ax
- test [pflags], PORT_BINARY ; Binary file?
- jnz @@nobump
- cmp bx, LF ; CR or LF just output?
- jne @@nobump
- inc ax ; yes bump # bytes written
- @@nobump:
- cmp ax, 100h ; Exceed chunk boundary?
- jle @@setbufpos
- sub ax, 100h ; ax = excess above chunk
- inc [(PORTDEF es:si).chunk]
- @@setbufpos:
- mov [(PORTDEF es:si).bufpos], ax
- @@return:
- xor ax, ax
- ret
- ENDP givechar
-
- END